#ifndef QMFCAPP_H
#define QMFCAPP_H

#include <QtWidgets/QApplication>

#if QT_VERSION >= 0x050000
#include <QtCore/QAbstractNativeEventFilter>

#if defined(QTMFCMIXER_LIBRARY)
#  define QTMFCMIXER_EXPORT __declspec(dllexport)
#else
#  define QTMFCMIXER_EXPORT __declspec(dllimport)
#endif

#if defined(_AFXDLL) && defined(_MSC_VER)
#define QTMFCMIXER_WITHMFC
class CWinApp;
#endif

/*
    QMfcAppEventFilter为事件循环中的消息过滤器。

    可重写此类，并调用QAbstractEventDispatcher::instance()
    ->installNativeEventFilter()将其实例绑定到全局消息过滤器，
    来对消息进行自定义处理。
*/
class QTMFCMIXER_EXPORT QMfcAppEventFilter : public QAbstractNativeEventFilter
{
public:
    QMfcAppEventFilter();
    bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
};
#endif

/*
    QMfcApp用于代理MFC原生的事件循环，以将Qt的事件循环与MFC的事件循环相融合。

    此类必须在创建任何依赖于Qt事件循环的对象之前创建（例如QWidget等）。
    此类一般用于以下两种情形：
    （1）MFC中调用基于Qt的Dll
        此时应在Qt Dll的main函数中，调用QMfcApp::pluginInstance(hInstance)
    拦截MFC的消息。例如：
    BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpvReserved)
    {
        static bool ownApplication = FALSE;

        if ( dwReason == DLL_PROCESS_ATTACH )
        ownApplication = QMfcApp::pluginInstance( hInstance );
        if ( dwReason == DLL_PROCESS_DETACH && ownApplication )
        delete qApp;

        return TRUE;
    }
    extern "C" __declspec(dllexport) void showDialog( HWND parent )
    {
        QMyDialog dlg;
        dlg.exec();
    }

    （2）MFC中直接调用Qt的API
        此时应使用Qt的事件循环系统替换MFC本身的事件循环。例如：
    BOOL CWinApp::InitInstance()
	{
		// MFC init.... 

		QMfcApp::instance(this);  

		// Qt init... 

		QMyDialog dlg;
		dlg.exec();
	}
    int CWinApp::Run()
    {
        return QMfcApp::run(this);
    }
*/
class QTMFCMIXER_EXPORT QMfcApp : public QApplication
{
public:
    //Qt Mfc
#ifdef QTMFCMIXER_WITHMFC
    static int run(CWinApp *mfcApp);
    static QApplication *instance(CWinApp *mfcApp);
    QMfcApp(CWinApp *mfcApp, int &argc, char **argv);    
#endif

    //Qt Dll
    static bool pluginInstance(Qt::HANDLE plugin = 0);
    static void enterModalLoop();
    static void exitModalLoop();
    QMfcApp(int &argc, char **argv);
    ~QMfcApp();
    bool winEventFilter(MSG *msg, long *result);

private:
#ifdef QTMFCMIXER_WITHMFC
    static char ** mfc_argv;
    static int mfc_argc;
    static CWinApp *mfc_app;
#endif

    int idleCount;
    bool doIdle;
};

#endif
